const fs = require('fs');
const path = require('path');
const http = require('http');
// 生成后的文件存放路径
const srcFolder = '../api/modules';
// 后端api文档地址
const url = 'http://localhost:9999/wit/wit-doc.json';
// 接口前缀
const api = '/wit';

function mkdirsSync(dirname) {
  if (fs.existsSync(dirname)) {
    return true;
  }
  if (mkdirsSync(path.dirname(dirname))) {
    fs.mkdirSync(dirname);
    return true;
  }
}

function getPath(pathUrl) {
  return path.resolve(__dirname, pathUrl);
}

function generateTemplate(arr) {
  return `import { createAPI } from '@/api/http';
import { Opts } from '@/api/opts';
`;
}

function generateFunc(name, summary, type = 'post', params) {
  const arr = name.slice(1).split('/');
  const fun = arr[arr.length - 1];
  const urls = api + name;
  return `
/**
 *  @description ${summary || ''}
 *  @name ${fun}
${params}
 *  @example 示例1
 *   onMounted(async () => {
 *     const { data } = await createUser({ data: { id: '1' } });
 *   });
 *  @example 示例2
 *  createUser({ data: { id: '1' } }).then(res => {});
 *  @example 示例3
 *  const { data } = await deleteUser({ params: { id: '1' } })
 */
export const ${fun} = (opts: Opts) =>
  createAPI({
    method: '${type}',
    url: '${urls}',
    opts,
  });
`;
}

function httpgetJson(url) {
  return new Promise((resolve, reject) => {
    http
      .get(url, (res) => {
        const { statusCode } = res;
        const contentType = res.headers['content-type'];

        let error;
        if (statusCode !== 200) {
          error = new Error('请求失败。' + `状态码: ${statusCode}`);
        } else if (contentType != 'application/json; charset=utf-8') {
          error = new Error('无效的 content-type.' + `期望 application/json 但获取的是 ${contentType}`);
        }
        if (error) {
          console.error(error.message);
          // 消耗响应数据以释放内存
          res.resume();
          return;
        }

        res.setEncoding('utf8');
        let rawData = '';
        res.on('data', (chunk) => {
          rawData += chunk;
        });
        res.on('end', () => {
          try {
            const parsedData = JSON.parse(rawData);
            resolve(parsedData);
          } catch (e) {
            reject(`错误: ${e.message}`);
          }
        });
      })
      .on('error', (e) => {
        reject(`错误: ${e.message}`);
      });
  });
}

async function main() {
  console.log('获取远程json文件中...');
  const { paths } = await httpgetJson(url);
  console.log('获取成功正在生成api文件');
  const obj = {};
  for (const name in paths) {
    const path = paths[name];
    let folder = '';
    if (path.post) {
      const tag = path.post.tags[0];
      const param = path.post.parameters;
      if (!tag) continue;
      const urlArray = name.slice(1).split('/');
      if (name.slice(1).split('/').length === 4) {
        folder = urlArray[1];
      } else if (name.slice(1).split('/')[0] !== tag) continue;
      if (obj[path.post.tags[0]]) {
        obj[path.post.tags[0]].push({ summary: path.post.summary, tag, name, type: 'post', folder, param });
      } else {
        obj[path.post.tags[0]] = [{ summary: path.post.summary, tag, name, type: 'post', folder, param }];
      }
    } else if (path.put) {
      const tag = path.put.tags[0];
      const param = path.put.parameters;
      if (!tag) continue;
      const urlArray = name.slice(1).split('/');
      if (name.slice(1).split('/').length === 4) {
        folder = urlArray[1];
      } else if (name.slice(1).split('/')[0] !== tag) continue;
      if (obj[path.put.tags[0]]) {
        obj[path.put.tags[0]].push({ summary: path.put.summary, tag, name, type: 'put', folder, param });
      } else {
        obj[path.put.tags[0]] = [{ summary: path.put.summary, tag, name, type: 'put', folder, param }];
      }
    } else if (path.get) {
      const param = path.get.parameters;
      const tag = path.get.tags[0];
      if (!tag) continue;
      const urlArray = name.slice(1).split('/');
      if (name.slice(1).split('/').length === 4) {
        folder = urlArray[1];
      } else if (name.slice(1).split('/')[0] !== tag) continue;
      if (obj[path.get.tags[0]]) {
        obj[path.get.tags[0]].push({
          summary: path.get.summary,
          tag,
          name: name.replace('/{id}', ''),
          type: 'get',
          folder,
          param,
        });
      } else {
        obj[path.get.tags[0]] = [
          { summary: path.get.summary, tag, name: name.replace('/{id}', ''), type: 'get', folder, param },
        ];
      }
    } else if (path.delete) {
      const param = path.delete.parameters;
      const tag = path.delete.tags[0];
      if (!tag) continue;
      const urlArray = name.slice(1).split('/');
      if (name.slice(1).split('/').length === 4) {
        folder = urlArray[1];
      } else if (name.slice(1).split('/')[0] !== tag) continue;
      if (obj[path.delete.tags[0]]) {
        obj[path.delete.tags[0]].push({
          summary: path.delete.summary,
          tag,
          name: name.replace('/{id}', ''),
          type: 'delete',
          folder,
          param,
        });
      } else {
        obj[path.delete.tags[0]] = [
          { summary: path.delete.summary, tag, name: name.replace('/{id}', ''), type: 'delete', folder, param },
        ];
      }
    }
    // console.log(name.replace('/{id}', ''));
  }
  for (const tagName in obj) {
    let jsString = '';
    const requestTypes = [];
    let folder = '';
    for (const item of obj[tagName]) {
      const params = [];
      if (item.param) {
        for (const p of item.param) {
          params.push(` *  @param  ${p.name} ${p.description} {${p.type}} ${p.required ? '必传参数' : ''}\n`);
        }
      }
      const str = params.toString();
      const requestType = requestTypes.filter((o) => o === item.type);
      if (requestType.length === 0) requestTypes.push(item.type);
      jsString += generateFunc(item.name, item.summary, item.type, str.replaceAll(',', ''));
      folder = item.folder;
    }
    jsString = generateTemplate(requestTypes) + jsString;
    if (folder) {
      mkdirsSync(getPath(`..${srcFolder}/${folder}`));
      fs.writeFileSync(getPath(`..${srcFolder}/${folder}/${tagName}.ts`), jsString);
      console.log(`${srcFolder}/modules/${folder}/${tagName}.ts`);
    } else {
      fs.writeFileSync(getPath(`${srcFolder}/${tagName}.ts`), jsString);
      console.log(`${srcFolder}/${tagName}.ts`);
    }
  }
  console.log('生成完毕');
}

main();
